﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XMK.Framework.DataAccess;
using XMK.Framework.Model;
using System.Data;
using XMK.Framework.Config;

namespace XMK.Framework.Data
{
    public static class DataHelper
    {
        /// <summary>
        /// 通过存储过程取得参数信息
        /// </summary>
        /// <param name="procInfo"></param>
        /// <returns></returns>
        public static List<ProcParaInfo> GetProcParaInfos(ProcInfo procInfo)
        {
            DbProvider provider = ConfigHelper.GetDbProvider(procInfo.DbConn);
            List<ProcParaInfo> list = null;
            if (provider.GetType() == typeof(SqlDbProvider))
            {
                list = SqlData.GetProcParaInfos(provider, procInfo.ProcName);
            }
            return list;
        }

        public static List<ProcInfo> GetProcInfos(string conn)
        {
            DbProvider provider = ConfigHelper.GetDbProvider(conn);
            List<ProcInfo> list = null;
            if (provider.GetType() == typeof(SqlDbProvider))
            {
                list = SqlData.GetProcInfos(provider);
            }
            return list;
        }

        /// <summary>
        /// 根据存储过程得到执行的命令
        /// </summary>
        /// <param name="procInfo"></param>
        /// <returns></returns>
        public static DbCmdHelper GetCmd(ProcInfo procInfo)
        {
            DbCmdHelper cmd;
            DbProvider provider = ConfigHelper.GetDbProvider(procInfo.DbConn);
            List<ProcParaInfo> list = GetProcParaInfos(procInfo);
            if (list != null && list.Count > 0){
                string[] arrParas;
                object[] arrObjects;
                arrParas = new string[list.Count];
                arrObjects = new object[list.Count];
                ProcParaInfo para;
                for (int i = 0; i < list.Count; i++)
                {
                    para = list[i];
                    arrParas[i] = para.ParaName;
                    // 先判断是否有对应的值，如果没有判断是否有默认的值
                    object o = procInfo.ParaValueDict[para.ParaName];
                    if(o == null) {
                        if(!string.IsNullOrEmpty(para.ParaDefault))
                        {
                            o = procInfo.ParaValueDict[para.ParaDefault];
                            if( o == null)
                                o = para.ParaDefault;
                        }
                    }
                    arrObjects[i] = o == null ? DBNull.Value : o;
                }
                cmd = new DbCmdHelper(provider, procInfo.ProcName, delegate()
                {
                    return DbCmdHelper.CreateParameters(provider, arrParas).ToArray();
                });
                cmd.SetParamValues(arrObjects);
            }
            else
            {
                cmd = new DbCmdHelper(provider, procInfo.ProcName);
            }
            return cmd;
        }



        public static bool ExecProc(List<ProcInfo> procInfos)
        {
            DbProvider provider = ConfigHelper.GetDbProvider(procInfos[0].DbConn);
            DbCmdInfo[] cmds = new DbCmdInfo[procInfos.Count];
            for (int n = 0; n < procInfos.Count; n++)
            {
                cmds[n] = GetCmd(procInfos[n]).DbCmdInfo;
            }
            return DbManager.ExecTrans(provider, cmds);
        }


        public static object ExecProc(ProcInfo procInfo, Dictionary<string, object> paras,OrderInfo order,PageInfo page)
        {
            DbCmdHelper cmd = GetCmd(procInfo);

            // 如果是返回查询单个model类型
            if (procInfo.ProcType == ProcType.Model)
            {
                Dictionary<string, object> dict = null;
                // 如果没有子项
                if (string.IsNullOrEmpty(procInfo.ListName))
                {
                    dict = DbManager.GetInfo<Dictionary<string, object>>(cmd, fill);
                }
                else
                {
                    string[] listName = procInfo.ListName.Split(',');
                    dict = DbManager.GetInfo<Dictionary<string, object>>(cmd,
                        delegate(out Dictionary<string, object> model, DataRow row, DataSet dataSet)
                        {
                            model = new Dictionary<string, object>();
                            for (int i = 0; i < row.Table.Columns.Count; i++)
                            {
                                model.Add(row.Table.Columns[i].ColumnName, row[row.Table.Columns[i].ColumnName]);
                                for (int n = 0; n < listName.Length; n++)
                                {
                                    if (dataSet.Tables.Count > n)
                                        model.Add(listName[n], DbManager.DataTableFullInfos<Dictionary<string, object>>(dataSet.Tables[n], fill));
                                }
                            }
                        });
                }
                return dict;
            }
            // 返回分页list
            else if (procInfo.ProcType == ProcType.PageList)
            {
                List<Dictionary<string, object>> dict = DbManager.GetPageInfos<Dictionary<string, object>>(cmd, page,fill);
                return dict;
            }
            // 返回list
            else if (procInfo.ProcType == ProcType.List)
            {
                List<Dictionary<string, object>> dict = DbManager.GetInfoList<Dictionary<string, object>>(cmd, fill);
                return dict;
            }
            else if (procInfo.ProcType == ProcType.NonQuery)
            {
                int dict = DbManager.ExecNonQuery(cmd);
                return dict;
            }
            return null;
        }
        
        /// <summary>
        /// 对象填充
        /// </summary>
        /// <param name="model"></param>
        /// <param name="row"></param>
        static void fill(out Dictionary<string, object> model, DataRow row)
        {
            model = new Dictionary<string, object>();
            for (int i = 0; i < row.Table.Columns.Count; i++)
            {
                model.Add(row.Table.Columns[i].ColumnName, row[row.Table.Columns[i].ColumnName]);
            }        
        }
    }
}
